package comunicacaoserial;
import javax.comm.*;
import java.io.*; 
//classe Principal
public class SComm implements SerialPortEventListener {
       //propriedades
       private String Porta;
       public String Dadoslidos;
       public int nodeBytes;
       private int baudrate;
       private int timeout;
       private CommPortIdentifier cp;
       private SerialPort porta;
       private OutputStream saida;
       private InputStream entrada;
       
       //indicadores
       private boolean isDadoLido = false;
       private boolean Leitura;
       private boolean Escrita;


       public SComm() {
              Porta = "COM1";
              baudrate = 9600;
              timeout = 1000;
       };
       //um Objeto ComObj é passado ao construtor
       //com detalhes de qual porta abrir
       //e informações sobre configurações
       public SComm( String p , int b , int t ){
              this.Porta = p;
              this.baudrate = b;
              this.timeout = t;
       };
       //habilita escrita de dados
       public void HabilitarEscrita(){
              Escrita = true;
              Leitura = false;
       }

       //habilita leitura de dados
       public void HabilitarLeitura(){
              Escrita = false;
              Leitura = true;
       }
       //Obtém o ID da PORTA
       public void ObterIdDaPorta(){
            try {
                cp =  CommPortIdentifier.getPortIdentifier(Porta);
                if ( cp == null ) {
                   System.out.println("A " + Porta + " nao existe!" );

                   System.out.println("ERRO!Abortando..." );

                   System.exit(1);
                }
                
            } catch (Exception e) {
                System.out.println("Erro durante o procedimento. STATUS" + e );                
                System.exit(1);
            }
       }
       //Abre a comunicação da porta
       public void AbrirPorta(){
            try {
                porta = (SerialPort)cp.open("SComm",timeout);
                
                System.out.println("Porta aberta com sucesso!");
                //configurar parâmetros
                porta.setSerialPortParams(baudrate,
                                          porta.DATABITS_8,
                                          porta.STOPBITS_1,
                                          porta.PARITY_NONE
                                          );
            } catch (Exception e) {
                
                System.out.println("Erro ao abrir a porta! STATUS: " + e );
                System.exit(1);
            }
       }
       //função que envie um bit para a porta serial
       public void EnviarUmaString(String msg){
              if (Escrita==true) {
                try {
                    saida = porta.getOutputStream();
                    System.out.println("FLUXO OK!");
                } catch (Exception e) {
                     System.out.println("Erro.STATUS: " + e );
                }
                try {
                   System.out.println("Enviando um byte para " + Porta );
                   System.out.println("Enviando : " + msg );
                   int cont=0;
                   while(cont < msg.length() ){
                       String d = msg.substring(cont, cont+1);
                       cont++;
                       saida.write(d.getBytes());
                       Thread.sleep(30);
                       saida.flush();
                    }
                } catch (Exception e) {
                   System.out.println("Houve um erro durante o envio. ");
                   System.out.println("STATUS: " + e );
                   System.exit(1);
                }
               } else {
                      System.exit(1);
               }
       }
       //leitura de dados na serial
       public void LerDados(){
              if (Leitura == true){
                try {
                    entrada = porta.getInputStream();
                    System.out.println("FLUXO OK!");
                } catch (Exception e) {
                    System.out.println("Erro.STATUS: " + e );
                    System.exit(1);
                }
                try {
                    porta.addEventListener(this);
                    System.out.println("SUCESSO. Porta aguardando...");
                } catch (Exception e) {
                    System.out.println("Erro ao criar listener: ");
                    System.out.println("STATUS: " + e);
                    System.exit(1);
                }
                porta.notifyOnDataAvailable(true);
                System.out.println("SUCESSO. Porta aguardando...2");
               }
             
       }

      
       //gerenciador de eventos de leitura na serial
       public void serialEvent(SerialPortEvent ev){
              switch (ev.getEventType()) {
               case SerialPortEvent.BI:
               case SerialPortEvent.OE:
               case SerialPortEvent.FE:
               case SerialPortEvent.PE:
               case SerialPortEvent.CD:
               case SerialPortEvent.CTS:
               case SerialPortEvent.DSR:
               case SerialPortEvent.RI:
               case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
                    break;
               case SerialPortEvent.DATA_AVAILABLE:
                    byte[] bufferLeitura = new byte[1];
                    try {
                        if ( entrada.available() >= 1 ) { //armazena 11 caracteres antes de guardar informação
                           nodeBytes = entrada.read(bufferLeitura); //pega o tamanho do buffer 11 bytes
                           Dadoslidos = new String(bufferLeitura); //armazena dados do buffer 11 caracteres
                           System.out.println("Informação lida: " + Dadoslidos); //imprime na saída padrão a string
                           System.out.println("n.o de bytes lidos : " + nodeBytes ); //imprime o tamanho de bytes
                           isDadoLido = true; //flag que indica que a informação ja foi armazenada na string DadosLidos
                          }
                       
                    } catch (Exception e) {
                      System.out.println("Erro durante a leitura: "  + e );
                    }
                    
                    break;
              }
       }
       //função que fecha a conexão
       public void FecharCom(){
              try {
                   porta.close();
                   System.out.println("CONEXAO FECHADA>>FIM..");
              } catch (Exception e) {
                   System.out.println("ERRO AO FECHAR. STATUS: " + e );
                   System.exit(0);
              }
       }
       //Acessores
       public String obterPorta(){
              return Porta;
       }
       public int obterBaudrate(){
              return baudrate;
       }
       public boolean getLeitura(){
           return Leitura;
       }
       public String getDados(){
           return Dadoslidos;
       }
       public boolean isDadoLido(){ //verifica se o dado ja pode ser lido
          if(isDadoLido){
                isDadoLido = false;
              return true;
          }
          return false;
        }
}
